Patch for #163214 (reported by Tommi Komulainen) and fixes some other
authorKristian Rietveld <kris@gtk.org>
Tue, 14 Jun 2005 22:26:04 +0000 (22:26 +0000)
committerKristian Rietveld <kristian@src.gnome.org>
Tue, 14 Jun 2005 22:26:04 +0000 (22:26 +0000)
2005-06-15  Kristian Rietveld  <kris@gtk.org>

Patch for #163214 (reported by Tommi Komulainen) and fixes some
other scrolling/validation related bugs along the why.

* gtk/gtktreeview.c (gtk_tree_view_size_request): run
do_validate_rows once and don't queue a size request there,
(gtk_tree_view_size_allocate): don't update vadj value without
reason, sync top_row/dy after the window sizes and adjustments
are in sync again,
(validate_visible_area): always update dy when scrolling,
manually set top_row here after changing the vadj (don't depend
on _adjustment_changed and top_row/dy sync to do this), since we
now always set top_row here correctly, we can always free
scroll_to_path at the end which avoids infinite expose loops,
(do_validate_rows): add queue_resize boolean, remove top_row/dy
sync here, we cannot do it safely at this place since the
window sizes and adjustments are out of sync,
(validate_rows), (validate_rows_handler): update call to
do_validate_rows().

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-8
gtk/gtktreeview.c

index c620755c1b02dfc1aac2feda7ec31d8b385b3a1f..daca101b5c8355b929479129ad33b205e4f0a033 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2005-06-15  Kristian Rietveld  <kris@gtk.org>
+
+       Patch for #163214 (reported by Tommi Komulainen) and fixes some
+       other scrolling/validation related bugs along the why.
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_request): run
+       do_validate_rows once and don't queue a size request there,
+       (gtk_tree_view_size_allocate): don't update vadj value without
+       reason, sync top_row/dy after the window sizes and adjustments
+       are in sync again,
+       (validate_visible_area): always update dy when scrolling,
+       manually set top_row here after changing the vadj (don't depend
+       on _adjustment_changed and top_row/dy sync to do this), since we
+       now always set top_row here correctly, we can always free
+       scroll_to_path at the end which avoids infinite expose loops,
+       (do_validate_rows): add queue_resize boolean, remove top_row/dy
+       sync here, we cannot do it safely at this place since the
+       window sizes and adjustments are out of sync,
+       (validate_rows), (validate_rows_handler): update call to
+       do_validate_rows().
+
 2005-06-14  Matthias Clasen  <mclasen@redhat.com>
 
        * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_name): Add a 
index c620755c1b02dfc1aac2feda7ec31d8b385b3a1f..daca101b5c8355b929479129ad33b205e4f0a033 100644 (file)
@@ -1,3 +1,24 @@
+2005-06-15  Kristian Rietveld  <kris@gtk.org>
+
+       Patch for #163214 (reported by Tommi Komulainen) and fixes some
+       other scrolling/validation related bugs along the why.
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_request): run
+       do_validate_rows once and don't queue a size request there,
+       (gtk_tree_view_size_allocate): don't update vadj value without
+       reason, sync top_row/dy after the window sizes and adjustments
+       are in sync again,
+       (validate_visible_area): always update dy when scrolling,
+       manually set top_row here after changing the vadj (don't depend
+       on _adjustment_changed and top_row/dy sync to do this), since we
+       now always set top_row here correctly, we can always free
+       scroll_to_path at the end which avoids infinite expose loops,
+       (do_validate_rows): add queue_resize boolean, remove top_row/dy
+       sync here, we cannot do it safely at this place since the
+       window sizes and adjustments are out of sync,
+       (validate_rows), (validate_rows_handler): update call to
+       do_validate_rows().
+
 2005-06-14  Matthias Clasen  <mclasen@redhat.com>
 
        * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_name): Add a 
index c620755c1b02dfc1aac2feda7ec31d8b385b3a1f..daca101b5c8355b929479129ad33b205e4f0a033 100644 (file)
@@ -1,3 +1,24 @@
+2005-06-15  Kristian Rietveld  <kris@gtk.org>
+
+       Patch for #163214 (reported by Tommi Komulainen) and fixes some
+       other scrolling/validation related bugs along the why.
+
+       * gtk/gtktreeview.c (gtk_tree_view_size_request): run
+       do_validate_rows once and don't queue a size request there,
+       (gtk_tree_view_size_allocate): don't update vadj value without
+       reason, sync top_row/dy after the window sizes and adjustments
+       are in sync again,
+       (validate_visible_area): always update dy when scrolling,
+       manually set top_row here after changing the vadj (don't depend
+       on _adjustment_changed and top_row/dy sync to do this), since we
+       now always set top_row here correctly, we can always free
+       scroll_to_path at the end which avoids infinite expose loops,
+       (do_validate_rows): add queue_resize boolean, remove top_row/dy
+       sync here, we cannot do it safely at this place since the
+       window sizes and adjustments are out of sync,
+       (validate_rows), (validate_rows_handler): update call to
+       do_validate_rows().
+
 2005-06-14  Matthias Clasen  <mclasen@redhat.com>
 
        * gdk/x11/gdkcursor-x11.c (gdk_cursor_new_from_name): Add a 
index 874413c7466d3738b266599a33af708d7a005359..95499c3deb07476a23cd306e4f8ca4930a7d92cf 100644 (file)
@@ -285,6 +285,8 @@ static gboolean validate_row             (GtkTreeView *tree_view,
                                          GtkTreePath *path);
 static void     validate_visible_area    (GtkTreeView *tree_view);
 static gboolean validate_rows_handler    (GtkTreeView *tree_view);
+static gboolean do_validate_rows         (GtkTreeView *tree_view,
+                                         gboolean     size_request);
 static gboolean validate_rows            (GtkTreeView *tree_view);
 static gboolean presize_handler_callback (gpointer     data);
 static void     install_presize_handler  (GtkTreeView *tree_view);
@@ -1776,7 +1778,7 @@ gtk_tree_view_size_request (GtkWidget      *widget,
    * sure we have some size. In practice, with a lot of static lists, this
    * should get a good width.
    */
-  validate_rows (tree_view);
+  do_validate_rows (tree_view, FALSE);
   gtk_tree_view_size_request_columns (tree_view);
   gtk_tree_view_update_size (GTK_TREE_VIEW (widget));
 
@@ -2020,7 +2022,6 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
   GList *tmp_list;
   GtkTreeView *tree_view;
   gboolean width_changed = FALSE;
-  gboolean dy_changed = FALSE;
   gint old_width = widget->allocation.width;           
 
   g_return_if_fail (GTK_IS_TREE_VIEW (widget));
@@ -2088,16 +2089,13 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
   tree_view->priv->vadjustment->lower = 0;
   tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->page_size, tree_view->priv->height);
 
-  if (tree_view->priv->vadjustment->value + allocation->height - TREE_VIEW_HEADER_HEIGHT (tree_view) > tree_view->priv->height)
-    {
-      double before = tree_view->priv->vadjustment->value;
-      gtk_adjustment_set_value (tree_view->priv->vadjustment,
-                               MAX (tree_view->priv->height - tree_view->priv->vadjustment->page_size, 0));
-      if (before != tree_view->priv->vadjustment->value)
-        dy_changed = TRUE;
-    }
-
   gtk_adjustment_changed (tree_view->priv->vadjustment);
+
+  /* now the adjustments and window sizes are in sync, we can sync toprow/dy again */
+  if (gtk_tree_row_reference_valid (tree_view->priv->top_row))
+    gtk_tree_view_top_row_to_dy (tree_view);
+  else
+    gtk_tree_view_dy_to_top_row (tree_view);
   
   if (GTK_WIDGET_REALIZED (widget))
     {
@@ -2142,9 +2140,6 @@ gtk_tree_view_size_allocate (GtkWidget     *widget,
          else
            gtk_widget_queue_draw (widget);
        }
-      
-      if (dy_changed)
-       gtk_widget_queue_draw (widget);
     }
 }
 
@@ -4657,6 +4652,9 @@ validate_visible_area (GtkTreeView *tree_view)
       path = gtk_tree_row_reference_get_path (tree_view->priv->scroll_to_path);
       if (path && !_gtk_tree_view_find_node (tree_view, path, &tree, &node))
        {
+          /* we are going to scroll, and will update dy */
+         update_dy = TRUE;
+
          gtk_tree_model_get_iter (tree_view->priv->model, &iter, path);
          if (GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_INVALID) ||
              GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_COLUMN_INVALID))
@@ -4916,6 +4914,34 @@ validate_visible_area (GtkTreeView *tree_view)
       update_dy = TRUE;
     }
 
+  /* if we scrolled to a path, we need to set the dy here,
+   * and sync the top row accordingly
+   */
+  if (tree_view->priv->scroll_to_path)
+    {
+      gint dy;
+
+      if (node != NULL)
+       dy = _gtk_rbtree_node_find_offset (tree, node) - area_above;
+      else
+       dy = 0;
+
+      gtk_adjustment_set_value (tree_view->priv->vadjustment, dy);
+
+      if (tree_view->priv->top_row)
+        {
+          gtk_tree_row_reference_free (tree_view->priv->top_row);
+          tree_view->priv->top_row = NULL;
+        }
+
+      tree_view->priv->top_row = gtk_tree_row_reference_new_proxy (G_OBJECT (tree_view), tree_view->priv->model, above_path);
+
+      need_redraw = TRUE;
+    }
+  else
+    gtk_tree_view_top_row_to_dy (tree_view);
+
+  /* update width/height and queue a resize */
   if (size_changed)
     {
       GtkRequisition requisition;
@@ -4923,6 +4949,7 @@ validate_visible_area (GtkTreeView *tree_view)
       /* We temporarily guess a size, under the assumption that it will be the
        * same when we get our next size_allocate.  If we don't do this, we'll be
        * in an inconsistent state if we call top_row_to_dy. */
+
       gtk_widget_size_request (GTK_WIDGET (tree_view), &requisition);
       tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
       tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
@@ -4931,35 +4958,6 @@ validate_visible_area (GtkTreeView *tree_view)
       gtk_widget_queue_resize (GTK_WIDGET (tree_view));
     }
 
-  /* if we scroll at all, always update dy and kill the top_row */
-  if (tree_view->priv->scroll_to_path &&
-      ! GTK_RBNODE_FLAG_SET (tree_view->priv->tree->root, GTK_RBNODE_DESCENDANTS_INVALID))
-    {
-      update_dy = TRUE;
-      if (tree_view->priv->top_row)
-        {
-         gtk_tree_row_reference_free (tree_view->priv->top_row);
-         tree_view->priv->top_row = NULL;
-       }
-    }
-
-  /* if we walk backwards at all, then we need to reset our dy. */
-  if (update_dy)
-    {
-      gint dy;
-      if (node != NULL)
-       {
-         dy = _gtk_rbtree_node_find_offset (tree, node) - area_above;
-       }
-      else
-       {
-         dy = 0;
-       }
-
-      gtk_adjustment_set_value (tree_view->priv->vadjustment, dy);
-      need_redraw = TRUE;
-    }
-
   if (tree_view->priv->scroll_to_path)
     {
       gtk_tree_row_reference_free (tree_view->priv->scroll_to_path);
@@ -5015,7 +5013,7 @@ initialize_fixed_height_mode (GtkTreeView *tree_view)
  */
 
 static gboolean
-do_validate_rows (GtkTreeView *tree_view)
+do_validate_rows (GtkTreeView *tree_view, gboolean queue_resize)
 {
   GtkRBTree *tree = NULL;
   GtkRBNode *node = NULL;
@@ -5135,18 +5133,16 @@ do_validate_rows (GtkTreeView *tree_view)
       /* We temporarily guess a size, under the assumption that it will be the
        * same when we get our next size_allocate.  If we don't do this, we'll be
        * in an inconsistent state when we call top_row_to_dy. */
+
       gtk_widget_size_request (GTK_WIDGET (tree_view), &requisition);
       tree_view->priv->hadjustment->upper = MAX (tree_view->priv->hadjustment->upper, (gfloat)requisition.width);
       tree_view->priv->vadjustment->upper = MAX (tree_view->priv->vadjustment->upper, (gfloat)requisition.height);
       gtk_adjustment_changed (tree_view->priv->hadjustment);
       gtk_adjustment_changed (tree_view->priv->vadjustment);
-      gtk_widget_queue_resize (GTK_WIDGET (tree_view));
-    }
 
-  if (gtk_tree_row_reference_valid (tree_view->priv->top_row))
-    gtk_tree_view_top_row_to_dy (tree_view);
-  else
-    gtk_tree_view_dy_to_top_row (tree_view);
+      if (queue_resize)
+        gtk_widget_queue_resize (GTK_WIDGET (tree_view));
+    }
 
   if (path) gtk_tree_path_free (path);
 
@@ -5158,7 +5154,7 @@ validate_rows (GtkTreeView *tree_view)
 {
   gboolean retval;
   
-  retval = do_validate_rows (tree_view);
+  retval = do_validate_rows (tree_view, TRUE);
   
   if (! retval && tree_view->priv->validate_rows_timer)
     {
@@ -5176,7 +5172,7 @@ validate_rows_handler (GtkTreeView *tree_view)
 
   GDK_THREADS_ENTER ();
 
-  retval = do_validate_rows (tree_view);
+  retval = do_validate_rows (tree_view, TRUE);
   if (! retval && tree_view->priv->validate_rows_timer)
     {
       g_source_remove (tree_view->priv->validate_rows_timer);